package com.matt.service.impl;

import com.aliyun.openservices.shade.com.alibaba.fastjson.JSON;
import com.dotflat.util.AssertUtil;
import com.dotflat.util.UuidUtil;
import com.google.common.collect.ImmutableMap;
import com.matt.commons.dto.sso.StaffDTO;
import com.matt.commons.exception.BusinessException;
import com.matt.commons.page.PagerQuery;
import com.matt.domain.course.*;
import com.matt.domain.courseV2.VendorCourse;
import com.matt.domain.courseV2.VendorCoursePackage;
import com.matt.foundation.DO.course.CourseAddDO;
import com.matt.foundation.DO.course.WebCoursePageDO;
import com.matt.foundation.constant.CourseConstant;
import com.matt.foundation.model.ErrorCode;
import com.matt.foundation.query.ClassesQuery;
import com.matt.foundation.query.CourseAreaQuery;
import com.matt.foundation.query.CourseQuery;
import com.matt.foundation.utils.CopyUtils;
import com.matt.foundation.vo.course.CourseAreaAddVo;
import com.matt.foundation.vo.course.CourseAreaBuildPageVo;
import com.matt.foundation.vo.course.CourseAreaBuildVo;
import com.matt.repository.CourseDetailRepository;
import com.matt.repository.CourseTemplate3Repository;
import com.matt.repository.base.CourseAllRepository;
import com.matt.repository.course.CourseChildRepository;
import com.matt.repository.course.CourseRepository;
import com.matt.repository.course.CourseRepository2;
import com.matt.repository.course.CourseTypeRepository;
import com.matt.repository.courseV2.VendorCoursePackageRepository;
import com.matt.repository.courseV2.VendorCourseRepository;
import com.matt.repository.teaching.CourseAreaPublicRepository;
import com.matt.service.CourseService;
import com.matt.service.courseV2.VendorCourseService;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang.StringUtils;
import org.assertj.core.util.Lists;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.data.domain.Page;
import org.springframework.data.domain.PageImpl;
import org.springframework.data.domain.PageRequest;
import org.springframework.scheduling.annotation.Async;
import org.springframework.stereotype.Service;

import javax.transaction.Transactional;
import java.util.*;
import java.util.stream.Collectors;

import static com.matt.foundation.model.ErrorCode.AREA_BUILD_COURSE_DUPLICATE;

;

/**
 * *******************************
 * Created by Ron.
 * form com.matt
 * on 2017/9/1
 * *******************************
 */
@Service
@Slf4j
public class CourseServiceImpl implements CourseService {

    @Autowired
    private CourseAllRepository courseAllRepository;

    @Autowired
    private CourseAreaPublicRepository courseAreaPublicRepository;

    @Autowired
    private VendorCourseRepository vendorCourseRepository;

    @Autowired
    private VendorCoursePackageRepository vendorCoursePackageRepository;


    @Autowired
    private CourseRepository courseRepository;

    @Autowired
    private CourseRepository2 courseRepository2;

    @Autowired
    private CourseTypeRepository courseTypeRepository;

    @Autowired
    private CourseTemplate3Repository courseTemplate3Repository;

    @Autowired
    private VendorCourseService courseService;

    @Value("${spring.profiles.active}")
    private String env;

    @Autowired
    CourseDetailRepository courseDetailRepository;

    @Autowired
    private CourseChildRepository courseChildRepository;

    private List<Map> convert(List<Map> typeList, List<Object[]> list) {
        list.forEach(o -> {
            Map map = new HashMap();
            map.put("typeCode", o[0]);
            map.put("typeName", o[1]);
            typeList.add(map);
        });
        return typeList;
    }

//    private Course modifyCourseType(Course course, String typeName, String areaId) {
//        List<Course> courseList = courseRepository.findByTypeNameAndTypeAndDeletedAndAreaIdOrderByTypeCodeDesc(typeName, CourseConstant.CourseType.AREA_BUILD.codeOf(), false, areaId);
//        if (Objects.nonNull(courseList) && courseList.size() > 0) {
//            course.setTypeCode(courseList.get(0).getTypeCode());
//        } else {
//            Long num = courseRepository.findMaxTypeCode(CourseConstant.CourseType.AREA_BUILD.codeOf(), areaId);
//            if (Objects.nonNull(num))
//                course.setTypeCode(num.intValue() + 1);
//            else
//                course.setTypeCode(1);
//        }
//        course.setTypeName(typeName);
//
//        return course;
//    }

    @Override
    public Page<WebCoursePageDO> getCourseByType(CourseQuery courseQuery, Integer type,Integer packageType) {
        List<WebCoursePageDO> list;
        Long totalCount;
        courseQuery.setCourseType(type);
        if (CourseConstant.CourseType.AREA_BUILD.codeOf() == type) {
            list = courseAllRepository.findCourseListByCondition(courseQuery);
            totalCount = courseAllRepository.countCourseListByCondition(courseQuery);
        } else {
            String age = null;
            if (AssertUtil.isNotEmpty(courseQuery.getMonthAge())){
                 age = String.valueOf(courseQuery.getMonthAge());
            }
            String week = null;
            if (AssertUtil.isNotEmpty(courseQuery.getWeek())){
                week = String.valueOf(courseQuery.getWeek());
            }
            if (AssertUtil.isNotEmpty(courseQuery.getCourseWeek())){
                week = String.valueOf(courseQuery.getCourseWeek());
            }
            String face = null;
            if (AssertUtil.isNotEmpty(courseQuery.getCourseFace())){
                face = String.valueOf(courseQuery.getCourseFace());
            }
            PagerQuery pagerQuery =  new PagerQuery();
            pagerQuery.setPageNum(courseQuery.getPageNum());
            pagerQuery.setPageSize( courseQuery.getPageSize());
            Page<VendorCourse>  vendorCourseList = courseService.courseListV2(courseQuery.getName(),age,week,face,packageType,pagerQuery);

            list = vendorCourseList.getContent().stream().map(o->{
                WebCoursePageDO po = new WebCoursePageDO();
                po.setName(o.getTitle());
                po.setTypeName(o.getLabel());
                po.setId(o.getId());
                return po;
            }).collect(Collectors.toList());
            totalCount = vendorCourseList.getTotalElements();
        }

        return new PageImpl<>(list, PageRequest.of(courseQuery.getPageNum(), courseQuery.getPageSize()), totalCount);
    }

    /**
     * CourseAddDO [ CourseTemplete3 [TeachingTempleteCourseVo] ]
     *
     * @param courseAddDO
     * @return 使用通用模板创建课程
     */
    @Override
    @Transactional
    public Course createCourseByCommonTemplete(String ticket, CourseAddDO courseAddDO, StaffDTO dto) {
        return null;
    }

    @Override
    public Course getCourseCommon(String courseId, Integer type) {
        Course one = courseRepository.getOne(courseId);
        if (Objects.isNull(one))
            throw new BusinessException(ErrorCode.MATERIAL_NOT_EXIST, "课程不存在！");
        // List<CourseTemplate3> template3List = Lists.newArrayList();
        // if (type == TeachingTempleteConstant.TEMPLETE_TYPE_ALL) {
        //     template3List = courseTemplate3Repository.findAll();
        //  } else {
        //     template3List = courseTemplate3Repository.findAll();
        // }
        // one.setCourseTemplate3List(template3List);
        return one;
    }

    @Override
    public Object getCourseCommonByPage(CourseAreaQuery query) {
        List<HashMap> list = courseAllRepository.findCourseCommonListByCondition(query);
        Long count = courseAllRepository.countCourseAreaByCondition(query);
        return new PageImpl<>(list, PageRequest.of(query.getPageNum(), query.getPageSize()), count);
    }

    /**
     * @param courseDetail
     * @return 更新或新增课程基本信息
     */
    @Async
    public CourseDetail saveCourseDetail(CourseDetail courseDetail) {
        CourseDetail saved = courseDetailRepository.findByCourseId(courseDetail.getCourseId());
        if (Objects.isNull(saved)) {
            saved = courseDetailRepository.save(courseDetail);
        } else {
            courseDetail.setId(saved.getId());
            saved = courseDetailRepository.saveAndFlush(courseDetail);
        }
        return saved;
    }

    @Override
    public Course getById(String courseId) {
        return courseRepository.getOne(courseId);
    }

    @Transactional
    @Override
    public Course createAreaCourse(StaffDTO staff, CourseAreaAddVo courseAreaAddVo) {

        CourseAreaBuildVo courseAreaVO = courseAreaAddVo.getCourseAreaVo();

        CourseType courseType = courseTypeRepository.findByAreaIdAndIdAndType(staff.getAreaId(), courseAreaVO.getTypeId(), 2);

        if (courseType == null){
            throw new BusinessException(ErrorCode.MATERIAL_NOT_EXIST, "指定的课程类型不存在");
        }

        //获取教学附件
        String attachments = JSON.toJSONString(courseAreaAddVo.getAttachments());

        if(StringUtils.isEmpty(courseAreaVO.getCourseId())){

            Course oldCourse = courseRepository.findByTypeAndTypeNameAndNameAndAreaId(CourseConstant.CourseType.AREA_BUILD.codeOf(), courseType.getTypeName(), courseAreaVO.getName(),staff.getAreaId());
            if (Objects.nonNull(oldCourse)) {
                throw new BusinessException(AREA_BUILD_COURSE_DUPLICATE, "园区课程名称重复");
            }

            courseAreaVO.setAttachments(attachments);

            Course course = new Course();
            course.setName(courseAreaVO.getName());

            course.setTypeId(courseType.getId());
            course.setTypeName(courseType.getTypeName());

            CourseTemplateAreaBuild courseTemplate3 = new CourseTemplateAreaBuild();
            CopyUtils.copyProperties(courseAreaVO, courseTemplate3);
            courseTemplate3Repository.save(courseTemplate3);
            course.setStatus(courseAreaVO.getStatus());

            course.setAreaId(staff.getAreaId());
            course.setCreatedId(staff.getId());
            course.setLastModifiedId(staff.getId());
            course.setLastModifiedName(staff.getRealName());

            course.setType(CourseConstant.CourseType.AREA_BUILD.codeOf()); //固定园区自建课程
            course.setTypeName(courseType.getTypeName());
            course.setTemplateType(3);
            course.setCourseTemplateId(courseTemplate3.getId());

            Course save = courseRepository.save(course);

            return save;
        }else{
            Course oldCourse = courseRepository.getOne(courseAreaVO.getCourseId());
            CourseTemplateAreaBuild courseTemplate3 = courseTemplate3Repository.getOne(oldCourse.getCourseTemplateId());

            CopyUtils.copyProperties(courseAreaVO, courseTemplate3);
            courseTemplate3.setAttachments(attachments);
            courseTemplate3Repository.save(courseTemplate3);

            oldCourse.setStatus(courseAreaVO.getStatus());
            oldCourse.setName(courseAreaVO.getName());
//            oldCourse.setTypeName(courseType.getTypeName());
//            oldCourse.setTypeCode(courseType.getTypeCode());

            oldCourse.setLastModifiedId(staff.getId());
            oldCourse.setLastModifiedName(staff.getRealName());

            Course save = courseRepository.save(oldCourse);

            return save;

        }

    }

    @Override
    public Page<CourseAreaBuildPageVo> courseAreaBuildPage(CourseAreaQuery query) {
        List<Object[]> objects = courseAllRepository.findCourseAreaBuildlListByCondition(query);
        List<CourseAreaBuildPageVo> list = objects.stream().map(o -> CourseAreaBuildPageVo.of(o)).collect(Collectors.toList());
        Long count = courseAllRepository.countCourseAreaBuildByCondition(query);
        PageImpl<CourseAreaBuildPageVo> courseAreaBuildPageVos = new PageImpl<>(list, PageRequest.of(query.getPageNum(), query.getPageSize()), count);
        return courseAreaBuildPageVos;
    }

    @Override
    public CourseAreaBuildVo getCourseAreaBuildByCourseId(String areaId, String courseId) {
        // TODO Auto-generated method stub
        List<CourseAreaBuildVo> list = courseAllRepository.getCourseAreaBuildByCourseId(areaId, courseId);
//        List<CourseAreaBuildVo> list = objects.stream().map(o -> CourseAreaBuildVo.of(o)).collect(Collectors.toList());
       if (list.size()>0){
           return list.get(0);
       }else {
           return  new CourseAreaBuildVo();
       }
    }

    @Override
    public boolean deleteCourseAreaBuildByCourseId(String areaId, String courseId) {

        Course course = courseRepository.findByAreaIdAndId(areaId, courseId);

        if (course == null){
            throw new BusinessException(ErrorCode.COURSE_NOT_EXISTD, "课程不存在");
        }

        courseRepository.delete(course);
        List<CourseChild> allChildById = courseChildRepository.findAllChildById(courseId);
        if (!allChildById.isEmpty()){
            courseChildRepository.deleteAll(allChildById);
        }


        return true;
    }

    @Override
    public List<Map> findAreaAllType(String areaId) {
        List<Map> mapList = Lists.newArrayList();
        List<Object[]> list = courseAllRepository.findAreaAllType(areaId, CourseConstant.CourseType.AREA_BUILD.codeOf());
        return convert(mapList, list);
    }

    @Override
    public List<VendorCoursePackage> findAreaPackages(String areaId){
        List<VendorCoursePackage> list = vendorCoursePackageRepository.findAll();
        return list;
    }

    @Override
    public Page<CourseChild> courseChildAreaBuildPage(CourseAreaQuery query) {
        List<CourseChild> childList = courseChildRepository.findChildById(query.getCourseId());
        Integer count = 0;
        if(null!=childList && childList.size()>0){
            count = childList.size();
        }
        PageImpl<CourseChild> courseChildren = new PageImpl<>(childList, PageRequest.of(query.getPageNum(), query.getPageSize()), count);
        for (CourseChild courseChild : courseChildren.getContent()) {
            //查询是否存在子章节
//            Integer countById = courseChildRepository.findCountById(courseChild.getId());
//            if(null!=countById && countById>0){
//                courseChild.setHasChild(true);
//            }
            Integer chapterNum = courseChildRepository.findCountByAncestorsId(courseChild.getAncestorsId());
            courseChild.setChapterNum(chapterNum);

        }

        return courseChildren;
    }


    @Transactional // 异常时回滚，保证数据一致性
    public CourseChild createCourseChild(StaffDTO staff, CourseChild courseChild){
        // 假设传入的 courseChild 是顶层，并且已经包含了 courseId
        if(null!=courseChild.getId()){
            //删除之前的章节信息
            courseChildRepository.deleteChildByParentId(courseChild.getId());
        }
        return this.setCourseChild(staff, courseChild, courseChild.getChildList(), courseChild.getCourseId());
    }

    @Transactional
    public CourseChild setCourseChild(StaffDTO staff, CourseChild courseChild, List<CourseChild> childList, String courseId) {
        // 设置创建者ID
        courseChild.setCreatedId(staff.getId());

        // 设置课程ID
        courseChild.setCourseId(courseId);

        if(courseChild.getType() == null){
            courseChild.setType(2);
        }

        // 保存当前章节（如果是顶层章节，则parentId为null）
        courseChild = courseChildRepository.save(courseChild);

        // 设置祖先ID（如果是顶层章节，则祖先ID为自己的ID）
        String ancestorsId = courseChild.getAncestorsId();
        if (ancestorsId == null) {
            ancestorsId = courseChild.getId();
            courseChild.setAncestorsId(ancestorsId);
        }


        // 递归处理子章节
        if (childList != null && !childList.isEmpty()) {
            for (CourseChild child : childList) {
                child.setParentId(courseChild.getId()); // 设置父级ID
//                child.setAncestorsId(ancestorsId + "," + child.getId()); // 更新祖先ID
                child.setAncestorsId(ancestorsId);
                // 递归调用将保存子章节并处理其子章节，同时传递 courseId
                this.setCourseChild(staff, child, child.getChildList(), courseId);
            }
        }

        return courseChild;
    }

    @Override
    public CourseChild courseChildDetail(String id) {
        // 1. 根据 ID 查询祖先级章节
        CourseChild ancestorsCourseChild = courseChildRepository.findById(id)
                .orElseThrow(() -> new RuntimeException("章节不存在"));

        // 2. 查询所有子章节（根据祖级查询）
        List<CourseChild> allChildren = courseChildRepository.findChildByAncestorsId(id);

        // 3. 构建章节树
        ancestorsCourseChild.setChildList(buildChapterTree(id, allChildren));

        return ancestorsCourseChild;
    }

    /**
     * 删除章节（包括所有子章节）
     * @param id
     * @return
     */
    @Transactional
    @Override
    public boolean removeCourseChildAll(String id) {
        int i = courseChildRepository.deleteByAncestorsId(id);

        return i>0?true:false;
    }

    /**
     * 修改章节
     * @param staff
     * @param courseChild
     * @return
     */
//    @Override
//    public CourseChild editCourseChild(StaffDTO staff, CourseChild courseChild) {
//
//        // 1. 先删除所有子章节
//        courseChildRepository.deleteChildByAncestorsId(courseChild.getId());
//
//        // 2. 修改保存当前章节
////        courseChild.setCreatedId(staff.getId());
//        courseChildRepository.save(courseChild);
//        String parentId = courseChild.getId(); // 获取当前章节的 ID，作为后续子章节的父级 ID
//        String ancestorsId = courseChild.getAncestorsId(); // 获取祖级 ID（如果当前章节是顶层章节，则祖级 ID 为自己的 ID）
//
//        // 设置课程ID
//        String courseId = courseChild.getCourseId();
//
//        // 如果当前章节是顶层章节，设置祖级 ID 为自己的 ID
//        if (ancestorsId == null) {
//            ancestorsId = parentId;
//            courseChild.setAncestorsId(ancestorsId); // 设置祖级 ID
//            courseChildRepository.save(courseChild); // 更新当前章节，保存祖级 ID
//        }
//
//        // 3. 如果当前章节有子章节，递归处理每个子章节
//        if (null != courseChild.getChildList() && !courseChild.getChildList().isEmpty()) {
//            for (CourseChild child : courseChild.getChildList()) {
//                child.setParentId(parentId); // 设置父级 ID
//                child.setAncestorsId(ancestorsId); // 设置祖级 ID
//                this.setCourseChild(staff, child, child.getChildList(),courseId); // 递归处理子章节
//            }
//        }
//
//        return courseChild;
//    }

    /**
     * 屏蔽章节
     * @param id
     * @return
     */
    @Override
    public boolean editStatus(String id,Integer status) {
        CourseChild courseChild = courseChildRepository.getOne(id);
        courseChild.setId(id);
        courseChild.setStatus(status);
        courseChildRepository.save(courseChild);

        return true;
    }

    /**
     * 获取当前章节子章节
     * @param id
     * @return
     */
    @Override
    public List<CourseChild> getChild(String id) {
        List<CourseChild> childList = courseChildRepository.findChildByParentId(id);
        if(null!=childList && childList.size()>0){
            for (CourseChild courseChild : childList) {
                //查询是否存在子章节
                Integer countById = courseChildRepository.findCountById(courseChild.getId());
                if(null!=countById && countById>0){
                    courseChild.setHasChild(true);
                }
            }
        }

        return childList;
    }

    /**
     * 新建课程
     * @param course
     * @return
     */
    @Override
    public Course createCourse(StaffDTO staff,Course course) {
        course.setAreaId(staff.getAreaId());
        course.setResource(1);
        if(null==course.getId()){
            course.setCreatedId(staff.getId());
            course.setCreated(new Date());
        }else{
            course.setLastModifiedId(staff.getId());
            course.setLastModifiedName(staff.getRealName());
            course.setLastModified(new Date());
        }

        return courseRepository.save(course);
    }

    /**
     * 课程列表
     * @param query
     * @return
     */
    @Override
    public Page<Course> courseList(ClassesQuery query) {
        List<Course> courses = courseRepository2.courseList(query);
        Integer count = courseRepository2.courseCount(query);

        PageImpl<Course> pageList = new PageImpl<>(courses, PageRequest.of(query.getPageNum(), query.getPageSize()), count);

        for (Course course : pageList.getContent()) {
            Integer childCount = courseChildRepository.findChildCountById(course.getId());
            course.setChapterNum(childCount);
        }

        return pageList;
    }

    /**
     * 直播录播课程列表
     * @param query
     * @return
     */
    @Override
    public Page<Course> courseLiveList(ClassesQuery query) {
        List<Course> courses = courseRepository2.courseLiveList(query);
        Integer count = courseRepository2.courseLiveCount(query);

        PageImpl<Course> pageList = new PageImpl<>(courses, PageRequest.of(query.getPageNum(), query.getPageSize()), count);

        for (Course course : pageList.getContent()) {
            Integer childCount = courseChildRepository.findChildCountById(course.getId());
            course.setChapterNum(childCount);
        }

        return pageList;
    }

    /**
     * 通过课程id查询所有的章节以及子章节
     * @param query
     * @return
     */
    @Override
    public List<CourseChild> getCourseChildList(CourseAreaQuery query) {

        List<CourseChild> allChapters = courseChildRepository.findAllChildById(query.getCourseId());

        if (allChapters != null && !allChapters.isEmpty()) {
            // 使用Map来快速查找章节，避免多次数据库查询
            Map<String, CourseChild> chapterMap = new HashMap<>();
            for (CourseChild chapter : allChapters) {
                chapterMap.put(chapter.getId(), chapter);
            }

            // 构建章节树
            List<CourseChild> rootChapters = new ArrayList<>();
            for (CourseChild chapter : allChapters) {
                if (chapter.getParentId() == null) { // 顶级章节
                    CourseChild rootChapter = buildChapterTree(chapterMap, chapter.getId());
                    rootChapters.add(rootChapter);
                }
            }

            return rootChapters;
        }

        return allChapters;
    }

    /**
     * 新增播放量
     * @param id
     */
    @Override
    public Course addPlayCount(String id) {
        Course one = courseRepository.getOne(id);
        one.setPlayCount(one.getPlayCount()+1);

        return courseRepository.save(one);
    }

    @Override
    public Page<CourseChild> courseListByTea(CourseAreaQuery query) {
        // 1. 分页参数校验（避免空值或非法值）
        int pageNum = query.getPageNum() == null ? 1 : query.getPageNum();
        int pageSize = query.getPageSize() == null ? 10 : query.getPageSize();
        pageNum = Math.max(pageNum, 1);
        pageSize = Math.max(pageSize, 1);

        List<Course> list = courseRepository.findAllByAreaId(query.getAreaId());
        if(!list.isEmpty()){
            List<String> collect = list.stream().map(Course::getId).collect(Collectors.toList());
            query.setCourseIds(collect);
        }else {
            query.setCourseId("-1");
        }
        // 2. 查询分页数据和总条数
        List<CourseChild> allChapters = courseRepository2.findAllChildByAreaIdAndName(query);
        Integer count = courseRepository2.findAllChildCounts(query);
        count = count == null ? 0 : count; // 总条数空值兜底

        // 3. 按要求保留 PageImpl 分页对象（注意：PageRequest 从0开始计数，需减1）
        PageImpl<CourseChild> pageList = new PageImpl<>(allChapters, PageRequest.of(pageNum - 1, pageSize), count);

        // 4. 构建树形结构并替换分页内容
        if (allChapters != null && !allChapters.isEmpty()) {
            Map<String, CourseChild> chapterMap = new HashMap<>();
            for (CourseChild chapter : allChapters) {
                chapter.setChildList(new ArrayList<>()); // 初始化子列表，避免空指针
                chapterMap.put(chapter.getId(), chapter);
            }

            List<CourseChild> rootChapters = new ArrayList<>();
            for (CourseChild chapter : allChapters) {
                String parentId = chapter.getParentId();
                // 修复：顶级章节包含 parentId 为 null 或空字符串的情况
                if (parentId == null || parentId.trim().isEmpty()) {
                    // 修复：加循环引用检测，避免栈溢出
                    CourseChild rootChapter = buildChapterTree1(chapterMap, chapter.getId(), new HashSet<>());
                    rootChapters.add(rootChapter);
                }
            }

            // 关键：用树形结构替换分页对象的原始数据，保留分页元信息
            pageList = new PageImpl<>(rootChapters, pageList.getPageable(), pageList.getTotalElements());
        }

        return pageList;
    }
    private CourseChild buildChapterTree1(Map<String, CourseChild> chapterMap, String parentId, Set<String> visitedIds) {
        // 检测循环引用：已访问过的ID直接返回，终止递归
        if (visitedIds.contains(parentId)) {
            log.warn("章节存在循环引用，终止递归！当前父ID：{}，已访问ID：{}", parentId, visitedIds);
            return chapterMap.get(parentId);
        }

        CourseChild parentChapter = chapterMap.get(parentId);
        if (parentChapter == null) {
            return null; // 父章节不存在，直接返回
        }

        visitedIds.add(parentId); // 标记当前ID为已访问
        List<CourseChild> children = new ArrayList<>();

        for (CourseChild chapter : chapterMap.values()) {
            if (parentId.equals(chapter.getParentId())) {
                // 递归构建子章节树，传入已访问集合
                CourseChild childChapter = buildChapterTree1(chapterMap, chapter.getId(), visitedIds);
                if (childChapter != null) {
                    children.add(childChapter);
                }
            }
        }

        visitedIds.remove(parentId); // 递归结束，移除标记（不影响其他分支）
        parentChapter.setChildList(children);
        return parentChapter;
    }

    /**
     * 构建章节树
     *
     * @param parentId    父级章节 ID
     * @param allChildren 所有子章节列表
     * @return 当前父级章节的子章节列表
     */
    private List<CourseChild> buildChapterTree(String parentId, List<CourseChild> allChildren) {
        List<CourseChild> children = new ArrayList<>();

        // 遍历所有章节，找到当前父级章节的子章节
        for (CourseChild child : allChildren) {
            if (parentId.equals(child.getParentId())) {
                // 递归查找子章节的子章节
                child.setChildList(buildChapterTree(child.getId(), allChildren));
                children.add(child);
            }
        }

        return children;
    }

    private CourseChild buildChapterTree(Map<String, CourseChild> chapterMap, String parentId) {
        CourseChild parentChapter = chapterMap.get(parentId);
        List<CourseChild> children = new ArrayList<>();

        for (CourseChild chapter : chapterMap.values()) {
            if (parentId.equals(chapter.getParentId())) {
                CourseChild childChapter = buildChapterTree(chapterMap, chapter.getId());
                children.add(childChapter);
            }
        }

        parentChapter.setChildList(children);
        return parentChapter;
    }


}
